import { ref, watch } from 'vue'
import type { PropertyPanelProps, Listener } from '../types'
import Modeling from 'bpmn-js/lib/features/modeling/Modeling.js'
import type { Moddle } from 'bpmn-moddle'
import { is } from 'bpmn-js/lib/util/ModelUtil'
import type { Element } from 'diagram-js/lib/model/Types'

interface ExecutionListenerElement {
  $type: string
  event: string
  class?: string
  expression?: string
  delegateExpression?: string
}

export function useListeners(props: PropertyPanelProps) {
  const listeners = ref<Listener[]>([])

  // 监听当前元素变化
  watch(
    () => props.currentElement,
    (element) => {
      if (element) {
        const extensionElements = element.businessObject.extensionElements?.values || []
        const executionListeners = extensionElements.filter(
          (item: ExecutionListenerElement) => item.$type === 'flowable:ExecutionListener',
        )

        listeners.value = executionListeners.map((listener: ExecutionListenerElement) => ({
          event: listener.event || getDefaultEvent(props.currentElement as Element),
          type: getListenerType(listener),
          value: getListenerValue(listener),
        }))
      } else {
        listeners.value = []
      }
    },
    { immediate: true },
  )

  // 获取监听器类型
  const getListenerType = (listener: ExecutionListenerElement): Listener['type'] => {
    if (listener.class) return 'class'
    if (listener.expression) return 'expression'
    if (listener.delegateExpression) return 'delegateExpression'
    return 'class'
  }

  // 获取监听器值
  const getListenerValue = (listener: ExecutionListenerElement): string => {
    return listener.class || listener.expression || listener.delegateExpression || ''
  }

  const handleAddListener = () => {
    listeners.value.push({
      event: getDefaultEvent(props.currentElement as Element),
      type: 'class',
      value: '',
    })
    updateListeners()
  }

  const handleRemoveListener = (index: number) => {
    listeners.value.splice(index, 1)
    updateListeners()
  }

  const handleListenerChange = () => {
    updateListeners()
  }

  const getDefaultEvent = (element: Element) => {
    return is(element, 'bpmn:SequenceFlow') ? 'take' : 'start'
  }

  const updateListeners = () => {
    if (!props.currentElement || !props.modeler) return

    const modeling = props.modeler.get('modeling') as Modeling
    const moddle = props.modeler.get('moddle') as Moddle

    // 创建新的监听器元素
    const executionListeners = listeners.value.map((listener) => {
      const listenerConfig: Record<string, unknown> = {
        event: listener.event,
      }

      switch (listener.type) {
        case 'class':
          listenerConfig.class = listener.value
          break
        case 'expression':
          listenerConfig.expression = listener.value
          break
        case 'delegateExpression':
          listenerConfig.delegateExpression = listener.value
          break
      }

      return moddle.create('flowable:ExecutionListener', listenerConfig)
    })

    // 获取或创建扩展元素
    let extensionElements = props.currentElement.businessObject.extensionElements
    if (!extensionElements) {
      extensionElements = moddle.create('bpmn:ExtensionElements', { values: [] })
    }

    // 过滤掉旧的监听器
    const otherElements = (extensionElements.values || []).filter(
      (item: ExecutionListenerElement) => item.$type !== 'flowable:ExecutionListener',
    )

    // 更新扩展元素
    extensionElements.values = [...otherElements, ...executionListeners]

    // 更新属性
    modeling.updateProperties(props.currentElement, {
      extensionElements: extensionElements,
    })
  }

  return {
    listeners,
    handleAddListener,
    handleRemoveListener,
    handleListenerChange,
  }
}
